﻿#include "pch.h"
#include "InputBox.h"
#include "MainWindow.h"
#include "Resource.h"

BEGIN_MESSAGE_MAP(MainWindow, CDialog)
    ON_COMMAND(IDC_MENU_ITEM_RESTART, OnMenuItemRestartClicked)
    ON_COMMAND(IDC_MENU_ITEM_SELECT_LEVEL, OnMenuItemSelectLevelClicked)
    ON_COMMAND(IDC_MENU_ITEM_UNDO, OnMenuItemUndoClicked)
    ON_MESSAGE(Const::UM_MAN_MOVED, OnManMoved)
    ON_MESSAGE(Const::UM_GOTO_LEVEL, OnGotoLevel)
    ON_MESSAGE(Const::UM_GAME_OVER, OnGameOver)
END_MESSAGE_MAP()

/**
 * 构造方法。
 * @param parent    父窗口
 */
MainWindow::MainWindow(CWnd* parent) :
    CDialog(IDD_MAIN_WINDOW, parent),
    mGame(NULL),
    mGameBoard(Const::GAME_BOARD_WIDTH, Const::GAME_BOARD_HEIGHT) {
}

/**
 * 析构方法。
 */
MainWindow::~MainWindow() {
    delete mGame;
}

/**
 * 初始化事件的响应方法。
 * @return 总是 TRUE
 */
BOOL MainWindow::OnInitDialog() {
    CDialog::OnInitDialog();

    // 创建状态栏
    CRect rect;
    mStatusBar.Create(WS_CHILD | WS_VISIBLE | WS_DISABLED, rect, this, AFX_IDW_STATUS_BAR);
    CDialog::GetWindowRect(rect);
    int parts[Const::STATUS_BAR_PART_COUNT] = { rect.Width() / Const::STATUS_BAR_PART_COUNT, rect.Width() };
    mStatusBar.SetParts(Const::STATUS_BAR_PART_COUNT, parts);

    // 创建游戏区域
    CRect gameBoardRect(0, 0, Const::GAME_BOARD_WIDTH, Const::GAME_BOARD_HEIGHT);
    mGameBoard.Create(NULL, NULL, WS_CHILD | WS_VISIBLE, gameBoardRect, this, 0);

    // 创建游戏
    mGame = new Game(this, mGameBoard.GetDrawer(), &mGameBoard);

    return TRUE;
}

/**
 * 游戏结束事件的响应方法。
 * @param wParam    全部通关则为 TRUE，否则为 FALSE
 * @return 总是零
 */
LRESULT MainWindow::OnGameOver(WPARAM wParam, LPARAM) {
    if (wParam) {
        AfxMessageBox(IDS_WON_ALL_OVER, MB_ICONINFORMATION);
    } else {
        AfxMessageBox(IDS_WON, MB_ICONINFORMATION);
    }

    return 0;
}

/**
 * 进入关卡事件的响应方法。
 * @param wParam    关卡数
 * @return 总是零
 */
LRESULT MainWindow::OnGotoLevel(WPARAM wParam, LPARAM) {
    CString text;
    text.Format(IDS_LEVEL, wParam);
    mStatusBar.SetText(text, 0, 0);
    text.Format(IDS_MOVE_COUNT, 0);
    mStatusBar.SetText(text, 1, 0);

    return 0;
}

/**
 * 小人移动事件的响应方法。
 * @param wParam    小人移动次数
 * @return 总是零
 */
LRESULT MainWindow::OnManMoved(WPARAM wParam, LPARAM) {
    CString text;
    text.Format(IDS_MOVE_COUNT, wParam);
    mStatusBar.SetText(text, 1, 0);
    return 0;
}

/**
 * "重玩本关"菜单项的单击响应方法。
 */
void MainWindow::OnMenuItemRestartClicked() {
    mGame->Restart();
}

/**
 * "选关"菜单项的单击响应方法。
 */
void MainWindow::OnMenuItemSelectLevelClicked() {
    // 显示输入窗口
    CString tipText;
    tipText.Format(IDS_PLEASE_INPUT_NUMBER, 1, Const::LEVEL_COUNT);
    InputBox inputBox(mGame->GetLevel(), 0, Const::LEVEL_COUNT, 1, this, tipText);
    if (inputBox.DoModal() == IDCANCEL) {
        return;
    }

    // 进入关卡
    int level = inputBox.GetIntValue();
    if (level != mGame->GetLevel()) {
        mGame->GotoLevel(level);
    }
}

/**
 * "回退"菜单项的单击响应方法。
 */
void MainWindow::OnMenuItemUndoClicked() {
    mGame->Undo();
}

/**
 * 在翻译事件之前调用的方法。
 * @param msg   事件
 * @return 事件在此被处理则返回 TRUE，否则返回 FALSE
 */
BOOL MainWindow::PreTranslateMessage(MSG* msg) {
    if (msg->message == WM_KEYDOWN) {
        return mGame->OnKeyPressed((UINT)msg->wParam);
    }

    return CWnd::PreTranslateMessage(msg);
}
